#===============================================================================
# Makefile for CBT++ libraries. 
#
#------------------------------------------------------------------------------
# K. James Durbin    					
#===============================================================================
# $Id: $
#------------------------------------------------------------------------------

# *******************************************************************
# ******** LOOK IN USER SETTINGS FOR SETUP OPTIONS ******************
# *******************************************************************
include $(CBT_ROOT)/makefiles/UserSettings.mk

#=============================================================================
# Elaborates on these user settings to produce frequently used paths. 
#=============================================================================
# 
include $(CBT_ROOT)/makefiles/Makefile.in 


#=============================================================================
#	Create compile options out of supplied include and library paths. 
#=============================================================================


ifeq ($(GCCVERSION),ICC)
#INCLUDES_CC = -I/local_home/kdurbin/include/stlport/ -I$(CBT_INC) -pthread 
INCLUDES_CC = -I$(CBT_INC) 

# Great for GCC compatibility, but doesn't give us 64-bit. 
# INCLUDES_CC = -I$(CBT_INC) -I/usr/include/ -I/usr/include/c++/3.2.3/ -I/usr/include/c++/3.2.3/ext/
else
INCLUDES_CC = -I$(CBT_INC) 
endif 
LIB_PATHS = -L$(CBT_LIB) 
OBJ_PATHS = -L$(CBT_OBJ) 


#=============================================================================
# Library Targets
#=============================================================================
# Define which files to include in the library.  MUST come before Forte.mk
# STLPort.mk, and so on. 

cbtbase = Sequence ParseUtils GetOption FASTAFile FileUtils MiscUtils \
	PrintUtils CLibraryAdditions Sequence3Bit

cbtmertools = Mer SimpleMerHash MerHashMap 

cbtformats = AceFile GenBankEntry 
# Crossmatch   To be replaced by CMParse 

cbtmisc = WgsSimulator RandomNumberGenerator
#cbtmisc = WgsSimulator SearchResult GraphTable HashSampleSearchEngine \
#	ReadingFrame OverlapGraph SeqSampler RandomNumberGenerator 

# cbtalgorithms = HMM SuffixTree SequenceAlignment 

libtargets = $(cbtbase) $(cbtmertools) $(cbtformats) $(cbtmisc)


# Rules for building with Forte 
#include $(CBT_ROOT)/makefiles/Forte.mk

# Rules for building with STLPort instead of built-in STL
# (Note: this is done both for performance comparisons, as well
#  as for debugging, since STLPort has a "safe" mode). 
#include $(CBT_ROOT)/makefiles/STLPort.mk


#=============================================================================
# Object files. 
#=============================================================================
# Build lists of object files from the targets. 

# Keep optimized, debug, and profile objects separate. 
# g and pg specify debug and debug+profile respectively.
targetobjs = $(libtargets:%=$(CBT_OBJ)/%.o)
gtargetobjs = $(libtargets:%=$(CBT_OBJ)/%.g.o)
pgtargetobjs =$(libtargets:%=$(CBT_OBJ)/%.pg.o)

targetincludes = $(libtargets:%=$(CBT_INC)/%.hh)

#==================================================================
#	Compilation rules
#==================================================================
# pstreams doesn't compile with GCC2
ifeq ($(GCCVERSION),GCC2)
all: $(CBT_LIB) $(CBT_OBJ) $(CBT_BIN) gzstream $(CBT_LIB)/libcbt.a 
endif 

ifeq ($(GCCVERSION),GCC3)	
all: $(CBT_LIB) $(CBT_OBJ) $(CBT_BIN) gzstream pstreams $(CBT_LIB)/libcbt.a 
endif 

ifeq ($(GCCVERSION),ICC)
all: $(CBT_LIB) $(CBT_OBJ) $(CBT_BIN) gzstream $(CBT_LIB)/libcbt.a 
#all: $(CBT_LIB) $(CBT_OBJ) $(CBT_BIN) gzstream pstreams $(CBT_LIB)/libcbt.a 
endif 

# Create any of the directories that don't exist. 
$(CBT_LIB): 
	mkdir $(CBT_LIB)
$(CBT_BIN):
	mkdir $(CBT_BIN)
$(CBT_OBJ):
	mkdir $(CBT_OBJ)

#==================================================================
#	External Libraries
#==================================================================
#
# While I'd like to have the number of external dependencies be zero
# a few things I find so useful, and lightweight, that I've included 
# them.  The libraries CBT++ currently depends on are:
# 
# libgzstream    A C++ wrapper for libz, to handle gzip encoding/decoding.
# pstreams       A C++ wrapper for posix process control (i.e. piping to commands)
# 

gzstream:  $(CBT_LIB)/libgzstream.a $(CBT_INC)/gzstream.h	

ifeq ($(GCCVERSION),ICC)

#icc -pthread -tpp2 $(INCLUDES_CC) -I$(CBT_ROOT)/gzstream -c -o $(CBT_ROOT)/gzstream/gzstream.o $(CBT_ROOT)/gzstream/gzstream.C 
$(CBT_LIB)/libgzstream.a:
	cd $(CBT_ROOT)/gzstream;
	icc -tpp2 $(INCLUDES_CC) -I$(CBT_ROOT)/gzstream -c -o $(CBT_ROOT)/gzstream/gzstream.o $(CBT_ROOT)/gzstream/gzstream.C 
	ar cr $(CBT_ROOT)/gzstream/libgzstream.a $(CBT_ROOT)/gzstream/gzstream.o
	cp $(CBT_ROOT)/gzstream/libgzstream.a $(CBT_LIB)
	ranlib $(CBT_LIB)/libgzstream.a 
	cp -f $(CBT_ROOT)/gzstream/gzstream.h $(CBT_INC)

else

$(CBT_LIB)/libgzstream.a: 	
	cd $(CBT_ROOT)/gzstream; make clean; make 
	cp $(CBT_ROOT)/gzstream/libgzstream.a $(CBT_LIB)
	ranlib $(CBT_LIB)/libgzstream.a 
	cp -f $(CBT_ROOT)/gzstream/gzstream.h $(CBT_INC)

endif 


# I've put in a modified version of pstream without the 
# namespace.  This only works for GCC3.  This doesn't compile 
# under GCC2.   
$(CBT_INC)/pstream.h: 	
	cp -f $(CBT_ROOT)/pstreams-0.42/pstream.nonamespace.h $(CBT_INC)/pstream.h

pstreams: $(CBT_INC)/pstream.h


#==================================================================
#	Local shared library rules. 
#==================================================================

# Rule to make a shared library... 
ifeq ($(OSTYPE),osx-apple)
# OSX has dylib
shared: $(CBT__LIB)/libcbt.dylib
dylib: $(CBT__LIB)/libcbt.dylib
else
# solib is for linux and solaris. 
shared: $(CBT_LIB)/libcbt.so 
solib: $(CBT_LIB)/libcbt.so 
endif 

#==================================================================
# Create Object Files Rules 
#==================================================================

# Make DEBUG enabled version
bug: $(CBT_LIB)/libcbt.g.a

# Make DEBUG and profile enabled version. 
prof: $(CBT_LIB)/libcbt.pg.a

# Compile individual C++ source files
$(CBT_OBJ)/%.o: $(CBT_SRC)/%.cc $(CBT_INC)/%.hh
	$(GCC) $(CCFLAGS) $(FASTFLAG) $(INCLUDES_CC) -o $(CBT_OBJ)/$*.o -c $(CBT_SRC)/$*.cc

# Compile with DEBUG individual C++ source files
$(CBT_OBJ)/%.g.o: $(CBT_SRC)/%.cc $(CBT_INC)/%.hh
	$(GCC) $(CCFLAGS) -g $(INCLUDES_CC) -o $(CBT_OBJ)/$*.g.o -c $(CBT_SRC)/$*.cc

# Compile with DEBUG and PROFILE individual C++ source files
$(CBT_OBJ)/%.pg.o: $(CBT_SRC)/%.cc $(CBT_INC)/%.hh
	$(GCC) $(CCFLAGS) -pg $(INCLUDES_CC) -o $(CBT_OBJ)/$*.pg.o -c $(CBT_SRC)/$*.cc

#==================================================================
# Static Library/Archive Rules 
#==================================================================

# Make object files into a compbio library archive
$(CBT_LIB)/libcbt.a: $(targetobjs) $(targetincludes)
	ar rc $@  $(targetobjs) $(CBT_ROOT)/gzstream/gzstream.o
	ranlib $@

# Make DEBUG object files into a library archive
$(CBT_LIB)/libcbt.g.a: $(gtargetobjs) $(CBT_ROOT)/gzstream/gzstream.o 
	ar rc $@  $(gtargetobjs) 
	ranlib $@

# Make DEBUG and PROFILE object files into a library archive
$(CBT_LIB)/libcbt.pg.a: $(pgtargetobjs) $(CBT_ROOT)/gzstream/gzstream.o
	ar rc $@  $(pgtargetobjs) 
	ranlib $@

#==================================================================
# Shared Library/Archive Rules 
#==================================================================
# I like to avoid shared libraries as much as possible. 

# .so library for Solaris/Linux
$(CBT_LIB)/libcbt.so : $(targetobjs) 
	$(GCC) -shared -o $@ -L$(CBT_LIB) $(targetobjs) -lstdc++ -lz -lm -lgzstream

# .dylib for OS X
$(CBT__LIB)/libcbt.dylib: $(targetobjs)
	$(GCC) -dynamiclib -o $(CBT__LIB)libcbt.dylib -L$(CBT_LIB) $(targetobjs) /home/hgsc/lib/libgzstream.a -lz -lm -lstdc++


#==================================================================
# Utilities
#==================================================================

install:
	echo No install procedure currently defined. 

clean: cleanobj cleanlib cleanbin  

cleanobj:
	rm -f $(CBT_OBJ)/*

cleanlib:
	rm -f $(CBT_LIB)/*

cleanbin:
	rm -f $(CBT_BIN)/*

squeaky:
	rm -f $(CBT_OBJ)/*
	rm -f $(CBT_LIB)/*
















